﻿using System;
using Agenda.Model.Enum;
using DDotNet.ORMapping.Attribute;
using DDotNet.ORMapping.Attribute.DirectAccess;
using DDotNet.ORMapping.OREntity;
using DDotNet.ORMapping.Validation;

namespace Agenda.Model.Entities
{
    /// <summary>
    /// Classe que Representa uma Única Entrada de Telefone
    /// </summary>
    [Serializable()]
    [DBMapping("MainDB")] 
    [DirectEntityMapping("tb_Telefone", AllowDelete = true, AllowInsert = true, AllowUpdate = true)]
    public sealed class Telefone : BusinessEntityBase
    {
        #region Campos

        private int _ID;
        private int _IDRegistroAgenda;
        private int _IDValidacao;
        private string _NumeroTelefone;
        private TipoTelefone _Tipo = TipoTelefone.Residencial;
        private string _Recado;
        private string _Ramal;
        private string _DDD = "11";
        private string _CodigoNacionalidade = "55";

        #endregion

        #region Propriedades

        /// <summary>
        /// Ramal do Telefone
        /// </summary>
        [PropertyMapping("Ramal", AllowNull = true, NullValue = "")]
        public string Ramal
        {
            get { return _Ramal; }
            set
            {
                _Ramal = value;
                base.MarkDirty("Ramal");
            }
        }

        /// <summary>
        /// DDD do Telefone
        /// </summary>
        [PropertyMapping("DDD")]
        public string DDD
        {
            get { return _DDD; }
            set
            {
                _DDD = value;
                base.MarkDirty("DDD");
            }
        }

        /// <summary>
        /// Código da Nacionalidade do Número (Ex: Brasil - "+55")
        /// </summary>
        [PropertyMapping("CodigoNacionalidade")]
        public string CodigoNacionalidade
        {
            get { return _CodigoNacionalidade; }
            set
            {
                _CodigoNacionalidade = value;
                base.MarkDirty("CodigoNacionalidade");
            }
        }

        /// <summary>
        /// Chave Primária da Entidade de Telefone
        /// </summary>
        [EntityPrimaryKey(true)]
        [PropertyMapping("IDTelefone")]
        public int ID
        {
            get { return _ID; }
            set
            {
                _ID = value;
                base.MarkDirty("ID");
            }
        }

        /// <summary>
        /// Chave Estrangeira da Entidade de Telefone para Indicar qual o Registro de Agenda que esta Entidade Pertence
        /// </summary>
        [EntityForeignKey("ID")]
        [PropertyMapping("IDRegistroAgenda")]
        public int IDRegistroAgenda
        {
            get { return _IDRegistroAgenda; }
            set
            {
                _IDRegistroAgenda = value;
                base.MarkDirty("IDRegistroAgenda");
            }
        }

        /// <summary>
        /// Chave Estrangeira da Entidade de Telefone para Indicar qual o ID da Validação do Registro de Agenda que esta Entidade Pertence
        /// </summary>
        [EntityForeignKey("IDValidacao")]
        [PropertyMapping("IDValidacao")]
        public int IDValidacao
        {
            get { return _IDValidacao; }
            set
            {
                _IDValidacao = value;
                base.MarkDirty("IDValidacao");
            }
        }

        /// <summary>
        /// Retorna o Número do Telefone (Sem Máscara)
        /// </summary>
        [PropertyMapping("Numero")]
        public string NumeroTelefone
        {
            get { return _NumeroTelefone; }
            set
            {
                _NumeroTelefone = value;
                base.MarkDirty("NumeroTelefone");
            }
        }

        /// <summary>
        /// Retorna o Tipo do Número do Telefone
        /// </summary>
        [PropertyMapping("TipoTelefone")]
        public TipoTelefone Tipo
        {
            get { return _Tipo; }
            set
            {
                _Tipo = value;
                base.MarkDirty("Tipo");
            }
        }

        /// <summary>
        /// Retorna o Nome da Pessoa para o Recado
        /// </summary>
        [PropertyMapping("Recado", AllowNull = true, NullValue = "")]
        public string Recado
        {
            get { return _Recado; }
            set
            {
                _Recado = value;
                base.MarkDirty("Recado");
            }
        }

        #endregion

        /// <summary>
        /// Adiciona as Regras de Validação na Entidade
        /// </summary>
        protected override void AddValidationRules()
        {
            // Adiciona Validações de Número de Telefone
            base.Validations.Add(
                new ValidationRule("NumeroTelefone.Requirido", "NumeroTelefone",
                                   "O Número do Telefone deve ser Preenchido",
                                   new ValidationRuleHandler(CommonRules.Instance.StringRequired)));

            base.Validations.Add(
                new ValidationRule("NumeroTelefone.Tamanho", "NumeroTelefone",
                                   "O Número do Telefone deve conter até 8 dígitos",
                                   new ValidationRuleHandler(CommonRules.Instance.StringMaxLength),
                                   new StringMaxLengthArgs(8)));
            

            // Adiciona Validações de Número de DDD
            base.Validations.Add(
                new ValidationRule("DDD.Requirido", "DDD",
                                   "O DDD do Telefone deve ser Preenchido",
                                   new ValidationRuleHandler(CommonRules.Instance.StringRequired)));

            base.Validations.Add(
                new ValidationRule("DDD.Tamanho", "DDD",
                                   "O DDD do Telefone deve conter até 2 dígitos",
                                   new ValidationRuleHandler(CommonRules.Instance.StringMaxLength),
                                   new StringMaxLengthArgs(2)));
            

            // Adiciona Validações de Código de Nacionalidade
            base.Validations.Add(
                new ValidationRule("CodigoNacionalidade.Requirido", "CodigoNacionalidade",
                                   "O Código de Nacionalidade do Telefone deve ser Preenchido",
                                   new ValidationRuleHandler(CommonRules.Instance.StringRequired)));

            base.Validations.Add(
                new ValidationRule("CodigoNacionalidade.Tamanho", "CodigoNacionalidade",
                                   "O Código de Nacionalidade do Telefone deve conter até 2 dígitos",
                                   new ValidationRuleHandler(CommonRules.Instance.StringMaxLength),
                                   new StringMaxLengthArgs(2)));
            


            // Adiciona Validações de Recado
            base.Validations.Add(
                new ValidationRule("Recado.Tamanho", "Recado",
                                   "O Nome para Recados deve conter até 50 dígitos",
                                   new ValidationRuleHandler(CommonRules.Instance.StringMaxLength),
                                   new StringMaxLengthArgs(50)));

            // Adiciona Validações de Ramal
            base.Validations.Add(
                new ValidationRule("Ramal.Tamanho", "Ramal",
                                   "O Ramal do Telefone deve conter até 10 dígitos",
                                   new ValidationRuleHandler(CommonRules.Instance.StringMaxLength),
                                   new StringMaxLengthArgs(10)));
        }

        #region Propriedades Customizadas para Automação dos Grid e Interface Gráfica

        /// <summary>
        /// Retorna o Número de Telefone com Máscara (Ex: 1234-5678)
        /// </summary>
        private string TelefoneComMascara
        {
            get
            {
                if (string.IsNullOrEmpty(this.NumeroTelefone))
                {
                    return string.Empty;
                }
                else if (this.NumeroTelefone.Length > 4)
                {
                    return (this.NumeroTelefone.Substring(0, this.NumeroTelefone.Length - 4) + "-" + this.NumeroTelefone.Substring(this.NumeroTelefone.Length - 4, 4));
                }
                else
                {
                    return this.NumeroTelefone;
                }
            }
        }

        /// <summary>
        /// Retorna o Número do Telefone já Formatada
        /// </summary>
        public string TelefoneFormatado
        {
            get
            {
                return (string.Format("+{0} ({1}) {2}", this.CodigoNacionalidade, this.DDD, this.TelefoneComMascara));
            }
        }

        #endregion

    }
}